package com.yy.studyspringboot.utils;

import lombok.extern.slf4j.Slf4j;
import org.springframework.cglib.beans.BeanCopier;
import org.springframework.cglib.core.Converter;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 属性复制，支持将同名的Long时间戳属性和Date类型属性相互转换
 *
 * @author dengts
 * @date 2018年7月12日
 */
@Component
@Slf4j
public class BeanUtilEx {
    private static BeanCopier beanCopier;

    public static void copyProperties(Object source, Object target) {
        Converter converter = new Converter() {

            @SuppressWarnings("rawtypes")
            @Override
            public Object convert(Object value, Class target, Object context) {
                if (value instanceof Long && target.equals(Date.class)) {
                    return new Date((Long) value);
                } else if (value instanceof Date && (target == long.class || target == Long.class)) {
                    return ((Date) value).getTime();
                } else if (value instanceof Integer && target.equals(BigDecimal.class)) {
                    return new BigDecimal((Integer) value);
                } else if (value instanceof BigDecimal && (target.equals(Integer.class) || target == int.class)) {
                    return ((BigDecimal) value).intValue();
                } else {
                    return value;
                }
            }
        };

        beanCopier = BeanCopier.create(source.getClass(), target.getClass(), true);
        beanCopier.copy(source, target, converter);
    }

    /**
     * 复制List
     */
    public static <T> List<T> copyList(List<?> source, Class<T> clazz) {
        if (CollectionUtils.isEmpty(source)) {
            return null;
        }
        List<T> target = new ArrayList<>();
        try {
            for (Object source2 : source) {
                T newInstance = clazz.newInstance();
                copyProperties(source2, newInstance);
                target.add(newInstance);
            }
        } catch (InstantiationException | IllegalAccessException e) {
//            log.error("CopyList失败", e);
        }
        return target;
    }

    /**
     * 将对象里面为null的字符串和数字类型设置默认值
     * @param obj
     * @param excludeField 需要排除的字段
     * @throws Exception
     */
    public static void setFeidValueNotNull(Object obj, List<String> excludeField) throws Exception {
        if (excludeField == null) {
            excludeField = new ArrayList<>();
        }
        for (Field field : obj.getClass().getDeclaredFields()) {
            if (excludeField.contains(field.getName())) {
                continue;
            }
            field.setAccessible(true);
            if (field.get(obj) == null) {
                if (field.getGenericType().toString().equals("class java.lang.String")) {
                    field.set(obj, "");
                } else if (field.getGenericType().toString().equals("class java.lang.Integer")) {
                    field.set(obj, 0);
                } else if (field.getGenericType().toString().equals("class java.lang.Double")) {
                    field.set(obj, 0.0);
                } else if (field.getGenericType().toString().equals("class java.lang.Long")) {
                    field.set(obj, 0L);
                } else if (field.getGenericType().toString().equals("class java.math.BigDecimal")) {
                    field.set(obj, BigDecimal.ZERO);
                }
            }
        }
    }
}